﻿using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace 凯蒽斯.page
{
    public partial class AxisBlockControl1 : UserControl
    {
        private string[] buttonNames = new string[512];
        private readonly DispatcherTimer _timer = new DispatcherTimer();
        private static bool[] bitArray; // 全局bit数组，需同步修改

        public AxisBlockControl1()
        {
            InitializeComponent();
            Generate256Buttons();

            // 关键1：监听UserControl的Loaded事件（切换页面回来时触发）
            this.Loaded += AxisBlockControl1_Loaded;

            _timer.Interval = TimeSpan.FromSeconds(1);
            _timer.Tick += async (s, e) => await Timer_TickAsync();
            _timer.Start();
        }

        // 关键2：切换页面回来时，主动刷新按钮状态
        private void AxisBlockControl1_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateButtonsByBitArray(); // 重新加载时，从bitArray恢复状态
        }

        // 定时器：每次Tick都刷新按钮（不再仅初始化时更新）
        private async Task Timer_TickAsync()
        {
            if (MainWindow.valuePairs.TryGetValue("plc时间", out object timeValue))
            {
                Int64[] sourceArray = timeValue as Int64[];
                if (sourceArray != null)
                {
                    ushort[] timeArray = Array.ConvertAll(sourceArray, item => (ushort)item);
                    int totalBits = timeArray.Length * 16;
                    bool[] newBitArray = new bool[totalBits];

                    // 提取bit到新数组
                    for (int i = 0; i < timeArray.Length; i++)
                    {
                        ushort value = timeArray[i];
                        for (int bitPos = 0; bitPos < 16; bitPos++)
                        {
                            int index = i * 16 + bitPos;
                            bool isSet = ((value >> (15 - bitPos)) & 1) == 1;
                            newBitArray[index] = isSet;
                        }
                    }

                    // 仅初始化时赋值全局bitArray（避免覆盖用户修改）
                    if (bitArray == null)
                    {
                        bitArray = newBitArray;
                    }

                    // 关键3：每次定时器触发都刷新按钮（确保切换后状态不丢失）
                    UpdateButtonsByBitArray();
                }
            }
        }

        // 从全局bitArray更新按钮状态（优化UI线程判断）
        private void UpdateButtonsByBitArray()
        {
            if (bitArray == null) return;

            // 优化：判断是否在UI线程，避免不必要的Invoke
            if (Dispatcher.CheckAccess())
            {
                RefreshButtonStates();
            }
            else
            {
                Dispatcher.Invoke(RefreshButtonStates);
            }
        }

        // 单独提取按钮刷新逻辑，便于复用
        private void RefreshButtonStates()
        {
            for (int i = 0; i < 256; i++)
            {
                if (this.FindName($"btn{i}") is Button btn)
                {
                    bool isBitSet = (i < bitArray.Length) ? bitArray[i] : false;
                    // 强制设置背景色和内容（避免WPF样式覆盖）
                    btn.Background = isBitSet ? Brushes.Red : Brushes.Green;
                    btn.Content = isBitSet ? "1" : "0";
                    // 可选：强制刷新控件渲染
                    btn.InvalidateVisual();
                }
            }
        }

        private void Generate256Buttons()
        {
            for (int i = 0; i < 256; i++)
            {
                Button btn = new Button();
                string name = $"btn{i}";
                btn.Name = name;
                buttonNames[i] = name;
                btn.Content = (i + 1).ToString();
                btn.Width = 100;
                btn.Height = 30;
                btn.Margin = new Thickness(1);
                btn.BorderBrush = Brushes.Gray;
                btn.BorderThickness = new Thickness(1);
                btn.Click += async (s, e) => await Btn_ClickAsync(s, e);
                btn.HorizontalContentAlignment = HorizontalAlignment.Center;
                btn.VerticalContentAlignment = VerticalAlignment.Center;
                btn.FontSize = 12;
                btn.Background = Brushes.White;
                this.RegisterName(name, btn);
                textBlockContainer.Children.Add(btn);
            }
        }

        private async Task Btn_ClickAsync(object sender, RoutedEventArgs e)
        {
            if (sender is not Button clickedButton) return;

            var iteam = MainWindow.modbusSettings.FirstOrDefault(x => x.Description == "plc时间");
            if (iteam == null)
            {
                MessageBox.Show("未找到'plc时间'的Modbus配置");
                return;
            }

            if (!int.TryParse(clickedButton.Name.Replace("btn", ""), out int btnNum))
            {
                MessageBox.Show("按钮名称格式错误（应为'btn+数字'）");
                return;
            }

            int startOffset = btnNum / 16;
            int offsetInGroup = btnNum % 16;
            int globalBitIndex = startOffset * 16 + offsetInGroup;

            if (bitArray == null || globalBitIndex >= bitArray.Length)
            {
                MessageBox.Show("bitArray未初始化或索引越界");
                return;
            }

            bool newBitValue = clickedButton.Background == Brushes.Green;
            ushort registerAddress = (ushort)(iteam.startAddress + startOffset);

            try
            {
                _timer.Stop();
                bitArray[globalBitIndex] = newBitValue;

                bool[] groupBits = new bool[16];
                Array.Copy(bitArray, startOffset * 16, groupBits, 0, 16);
                ushort registerValue = ConvertBoolArrayToUshort(groupBits);

                await MainWindow.modbusHelp.WriteSingleRegisterAsync(
                    (byte)iteam.unitId,
                    registerAddress,
                    registerValue
                ).ConfigureAwait(true);

                // 点击后立即刷新当前按钮（确保视觉同步）
                clickedButton.Background = newBitValue ? Brushes.Red : Brushes.Green;
                clickedButton.Content = newBitValue ? "1" : "0";
                clickedButton.InvalidateVisual(); // 强制渲染
            }
            catch (Exception ex)
            {
                bitArray[globalBitIndex] = !newBitValue;
                clickedButton.Background = !newBitValue ? Brushes.Red : Brushes.Green;
                MessageBox.Show($"写入失败：{ex.Message}\n地址：{registerAddress}");
            }
            finally
            {
                _timer.Start();
            }
        }

        public static ushort ConvertBoolArrayToUshort(bool[] bitArray)
        {
            ushort result = 0;
            if (bitArray == null) return result;

            for (int j = 0; j < 16; j++)
            {
                bool isSet = (j < bitArray.Length) ? bitArray[j] : false;
                if (isSet)
                {
                    result |= (ushort)(1 << (15 - j));
                }
            }
            return result;
        }
    }
}